[iOS 10] iOS 10以降のAVFoundationでの撮影方法
AVFoundation
こんにちは!
モバイルアプリサービス部の田中孝明です。
iOSアプリで写真を撮る場合、UIImagePickerController
を用いる方法がありますが、AR等、他のViewをOverlayしたい場合、できることが限られるためAVFoundationを使ってカメラからの写真データを使って加工することが常套手段でした。
しかし、iOS 9から写真データ取得に使っていたAVCaptureStillImageOutput
がdeprecated
になり、代わりにiOS 10から追加されたAVCapturePhotoOutput
を使うようになりました。
今回はAVCapturePhotoOutput
を使った写真データ取得をやってみたいと思います。
AVCaptureSessionの設定
今回利用するクラスはキャプチャに関する入出力を管理するクラスのAVCaptureSession
と、キャプチャした映像をプレビューするAVCaptureVideoPreviewLayer
と、そして写真データを取得するAVCapturePhotoOutput
です。
private var session: AVCaptureSession? private var videoPreviewLayer: AVCaptureVideoPreviewLayer? private var stillImageOutput: AVCapturePhotoOutput?
AVCaptureSession
とAVCaptureVideoPreviewLayer
を設定します。
こちらはiOS 9までの方法と差異はありません。
session = AVCaptureSession() session?.sessionPreset = AVCaptureSessionPresetPhoto videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session) guard let _videoPreviewLayer = videoPreviewLayer else { return } _videoPreviewLayer.masksToBounds = true _videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill videoPreviewView.layer.addSublayer(_videoPreviewLayer) let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) let input = try! AVCaptureDeviceInput(device: device) session?.addInput(input)
AVCaptureSession
の出力にAVCaptureStillImageOutput
を設定していた処理がAVCapturePhotoOutput
に置き換わります。
stillImageOutput = AVCapturePhotoOutput() session?.addOutput(stillImageOutput)
AVCapturePhotoOutputでの撮影
AVCapturePhotoOutput
のcapturePhoto(with settings: AVCapturePhotoSettings, delegate: AVCapturePhotoCaptureDelegate)
メソッドをコールすることでキャプチャ先から撮影データを取得することができます。
AVCapturePhotoSettings
は撮影データに関する設定が色々できそうですので、別の機会で説明できればと思います!
func takePhoto() { let settingsForMonitoring = AVCapturePhotoSettings() settingsForMonitoring.flashMode = .auto settingsForMonitoring.isAutoStillImageStabilizationEnabled = true settingsForMonitoring.isHighResolutionPhotoEnabled = false stillImageOutput?.capturePhoto(with: settingsForMonitoring, delegate: self) }
撮影データの結果に関してはAVCapturePhotoCaptureDelegate
のデリゲートメソッドに通知されます。撮影データを加工したり、アルバムに保存したりする場合はこちらで行います。
// MARK: - AVCapturePhotoCaptureDelegate extension ViewController: AVCapturePhotoCaptureDelegate { func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) { // did receive photo data } }
まとめ
AVFoundationを使ったカメラアプリは歴史が古く、独自でライブラリを組まれている方も多いと思います。
AVCaptureStillImageOutput
がdeprecated
になったタイミングでSwift 3.0への移行も兼ねて新設するのもいいのではないでしょうか?
参考文献
AVCapturePhotoOutput - Beyond the Basics
AVCapturePhotoOutput
AVCapturePhotoSettings